<?php


namespace EchoPHP\Session;

use EchoPHP\Support\Arr;

class MemcacheStore {

    /**
     * session是否已经开启标记
     * @var bool
     */
    protected $start = false;

    /**
     * 会话id
     * @var
     */
    protected $sessionId;

    public function __construct($sessionId = null) {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            $this->start($sessionId);
        } else {
            $this->start = true;
        }
    }

    /**
     * 开启session会话
     * @param string $sessionId 会话id
     */
    protected function start($sessionId = null) {
        if (!empty($sessionId)) {
            $this->setId($sessionId);
        }

        session_start();
        $this->start = true;
    }

    /**
     * 判断会话是否已经开启
     * @return bool
     */
    public function isStart() {
        return $this->start;
    }

    /**
     * 获取sessionid
     * @param bool $refresh 是否重新获取最新的sessionid
     * @return string
     */
    public function getId($refresh = false) {
        if (!$this->sessionId || $refresh) {
            $this->sessionId = session_id();
        }
        return $this->sessionId;
    }

    /**
     * 重新指定新的会话id， 不会清楚会话数据
     * @param null $id
     * @return string 最新的会话id
     */
    public function setId($id = null) {
        if (empty($id)) {
            session_regenerate_id();
        } elseif (!$this->start) {
            session_id($id);
        }
        return $this->getId(true);
    }

    /**
     * 重新生成session
     * @param bool $delete 是否删除关联会话文件数据
     * @return string 最新的会话id
     */
    public function regenerate($delete = false) {
        session_regenerate_id($delete);
        return $this->getId(true);
    }

    /**
     * 判断session内容是否存在
     * @param $key
     * @return bool
     */
    public function exists($key) {
        return Arr::has($_SESSION, $key);
    }

    /**
     * 判断session内容是否存在且非空
     * @param $key
     * @return bool
     */
    public function has($key) {
        $value = $this->get($key);
        return !is_null($value) && !empty($value);
    }

    /**
     * 从session中获取一个值
     * @param $key
     * @param null $default
     * @return mixed
     */
    public function get($key, $default = null) {
        return Arr::get($_SESSION, $key, $default);
    }

    /**
     * 从session中获取一个值并将其从session中移除
     * @param $key
     * @param null $default
     * @return mixed
     */
    public function pull($key, $default = null) {
        return Arr::pull($_SESSION, $key, $default);
    }

    /**
     * 获取全部session内容
     * @return mixed
     */
    public function all() {
        return $_SESSION;
    }

    /**
     * 添加session值， 支持批量添加数组或者单个添加, 键名如果存在会被替换
     * @param $key
     * @param null $value
     */
    public function set($key, $value = null) {
        if (!is_array($key)) {
            $key = [$key => $value];
        }
        foreach ($key as $keyName => $keyValue) {
            Arr::set($_SESSION, $keyName, $keyValue);
        }
    }

    /**
     * 向session的数组格式值中加入追加一个值
     * @param $key
     * @param $value
     */
    public function push($key, $value) {
        $array = $this->get($key, []);
        if (!is_array($array)) {
            return;
        }

        $array[] = $value;
        $this->set($key, $array);
    }

    /**
     * 自增
     * @param $key
     * @param int $step
     * @return int
     */
    public function increment($key, int $step = 1) {
        $value = (int)$this->get($key, 0) + $step;
        $this->set($key, $value);
        return $value;
    }

    /**
     * 自减
     * @param $key
     * @param int $step
     * @return int
     */
    public function decrement($key, int $step = 1) {
        $value = (int)$this->get($key, 0) - $step;
        $this->set($key, $value);
        return $value;
    }

    /**
     * 删除一个session变量
     * @param $key
     */
    public function delete($key) {
        Arr::remove($_SESSION, $key);
    }

    /**
     * 删除所有session变量
     */
    public function flush() {
        //重置sessionid
//        $this->setId();
        session_destroy();
        session_unset();

        $_SESSION = [];

    }

}